<script setup lang="ts">
  import { useI18n } from "vue-i18n";
  import { onMounted, nextTick } from "vue";
  import DOMPurify from "dompurify";
  import { route } from "../../lib/api/base";
  import { toast, Toaster } from "@/components/ui/sonner";
  import { Separator } from "@/components/ui/separator";
  import { Button } from "@/components/ui/button";
  import { Label } from "@/components/ui/label";
  import { Input } from "@/components/ui/input";
  import { Checkbox } from "@/components/ui/checkbox";
  import MdiMapMarker from "~icons/mdi/map-marker";
  import MdiMapMarkerOff from "~icons/mdi/map-marker-off";
  import MdiPrinter from "~icons/mdi/printer";

  const { t } = useI18n();

  definePageMeta({
    middleware: ["auth"],
  });
  useHead({
    title: "HomeBox | " + t("reports.location_label_generator.title"),
  });

  const api = useUserApi();

  const bordered = ref(false);

  /**
   * 显示属性配置对象
   * 用于控制标签生成器的各种参数设置
   */
  const displayProperties = reactive({
    baseURL: window.location.origin,  // 当前网站的基础URL，用于生成二维码链接
    locationRange: 1,                 // 起始位置ID（从1开始）
    locationRangeMax: 4,            // 结束位置ID（默认4个，方便测试查看）
    measure: "mm",                    // 尺寸单位（in=英寸，mm=毫米）- 使用毫米更节省纸张
    gapY: 1,                          // 标签之间的垂直间距（毫米）
    columns: 2,                       // 每页显示的列数
    cardHeight: 40,                   // 单个标签的高度（毫米）- 更小更节省纸张
    cardWidth: 40,                    // 单个标签的宽度（毫米）- 更小更节省纸张
    pageWidth: 210,                   // 页面总宽度（A4纸宽度210mm）
    pageHeight: 297,                  // 页面总高度（A4纸高度297mm）
    pageTopPadding: 5,                // 页面上边距（毫米）- 更小边距节省纸张
    pageBottomPadding: 5,             // 页面下边距（毫米）- 更小边距节省纸张
    pageLeftPadding: 5,               // 页面左边距（毫米）- 更小边距节省纸张
    pageRightPadding: 5,              // 页面右边距（毫米）- 更小边距节省纸张
    includeURLInQR: true,             // 是否在二维码中包含完整网址
  });

  type LabelOptionInput = {
    measure: string;
    page: {
      height: number;
      width: number;
      pageTopPadding: number;
      pageBottomPadding: number;
      pageLeftPadding: number;
      pageRightPadding: number;
    };
    cardHeight: number;
    cardWidth: number;
  };

  type Output = {
    measure: string;
    cols: number;
    rows: number;
    gapY: number;
    gapX: number;
    card: {
      width: number;
      height: number;
    };
    page: {
      width: number;
      height: number;
      pt: number;
      pb: number;
      pl: number;
      pr: number;
    };
  };

  /**
   * 计算网格数据
   * 根据输入参数计算标签在页面上的布局信息
   * @param input - 标签选项输入参数
   * @returns 计算后的输出数据
   */
  function calculateGridData(input: LabelOptionInput): Output {
    const { page, cardHeight, cardWidth } = input;

    const measureRegex = /in|cm|mm/;
    const measure = measureRegex.test(input.measure) ? input.measure : "in";

    const availablePageWidth = page.width - page.pageLeftPadding - page.pageRightPadding;
    const availablePageHeight = page.height - page.pageTopPadding - page.pageBottomPadding;

    if (availablePageWidth < cardWidth || availablePageHeight < cardHeight) {
      toast.error(t("reports.label_generator.toast.page_too_small_card"));
      return out.value;
    }

    const cols = Math.floor(availablePageWidth / cardWidth);
    const rows = Math.floor(availablePageHeight / cardHeight);
    // 避免除零错误，当只有一列或一行时，间距为0
    const gapX = cols > 1 ? (availablePageWidth - cols * cardWidth) / (cols - 1) : 0;
    const gapY = rows > 1 ? (page.height - rows * cardHeight) / (rows - 1) : 0;

    return {
      measure,
      cols,
      rows,
      gapX,
      gapY,
      card: {
        width: cardWidth,
        height: cardHeight,
      },
      page: {
        width: page.width,
        height: page.height,
        pt: page.pageTopPadding,
        pb: page.pageBottomPadding,
        pl: page.pageLeftPadding,
        pr: page.pageRightPadding,
      },
    };
  }

  interface InputDef {
    label: string;
    ref: keyof typeof displayProperties;
    type?: "number" | "text";
  }

  const propertyInputs = computed<InputDef[]>(() => {
    return [
      {
        label: t("reports.location_label_generator.location_start"),
        ref: "locationRange",
      },
      {
        label: t("reports.location_label_generator.location_end"),
        ref: "locationRangeMax",
      },
      {
        label: t("reports.label_generator.measure_type"),
        ref: "measure",
        type: "text",
      },
      {
        label: t("reports.label_generator.label_height"),
        ref: "cardHeight",
      },
      {
        label: t("reports.label_generator.label_width"),
        ref: "cardWidth",
      },
      {
        label: t("reports.label_generator.page_width"),
        ref: "pageWidth",
      },
      {
        label: t("reports.label_generator.page_height"),
        ref: "pageHeight",
      },
      {
        label: t("reports.label_generator.page_top_padding"),
        ref: "pageTopPadding",
      },
      {
        label: t("reports.label_generator.page_bottom_padding"),
        ref: "pageBottomPadding",
      },
      {
        label: t("reports.label_generator.page_left_padding"),
        ref: "pageLeftPadding",
      },
      {
        label: t("reports.label_generator.page_right_padding"),
        ref: "pageRightPadding",
      },
      {
        label: t("reports.label_generator.base_url"),
        ref: "baseURL",
        type: "text",
      },
    ];
  });

  /**
   * 位置标签数据结构定义
   * 用于存储每个标签需要显示的信息
   */
  type LocationLabelData = {
    url: string;      // 二维码中包含的完整URL
    name: string;     // 位置名称
    locationID: string; // 格式化的位置ID（如0001、0002）
    description: string; // 位置描述信息
  };

  /**
   * 格式化位置ID
   * 将数字转换为4位字符串，不足补零（如1→0001，12→0012）
   * @param lid - 位置ID数字或字符串
   * @returns 格式化的4位字符串
   */
  function fmtLocationID(lid: number | string) {
    lid = lid.toString();
    let lidStr = lid.toString().padStart(4, "0");
    return lidStr;
  }

  /**
   * 生成位置二维码URL
   * 根据位置ID生成对应的二维码图片URL，使用后端API生成二维码
   * @param locationID - 位置ID
   * @returns 二维码图片URL
   */
  function getLocationQRCodeUrl(locationID: string): string {
    let origin = displayProperties.baseURL.trim();

    // 移除末尾的斜杠
    if (origin.endsWith("/")) {
      origin = origin.slice(0, -1);
    }

    // 根据选项决定二维码内容
    let data: string;
    if (displayProperties.includeURLInQR) {
      // 包含完整网址
      data = `${origin}/location/${locationID}`;
    } else {
      // 只包含相对路径
      data = `/location/${locationID}`;
    }

    // 调用后端API生成二维码 - 使用完整的URL格式，添加合适的尺寸参数
    const qrUrl = `${origin}/api/v1/qrcode?data=${encodeURIComponent(data)}&size=256`;
    
    console.log(`生成二维码URL: ${locationID} -> ${data} -> ${qrUrl}`);
    
    return qrUrl;
  }

  const out = ref<Output>({
    measure: "mm",
    cols: 0,
    rows: 0,
    gapX: 0,
    gapY: 0,
    card: {
      width: 0,
      height: 0,
    },
    page: {
      width: 0,
      height: 0,
      pt: 0,
      pb: 0,
      pl: 0,
      pr: 0,
    },
  });

  const { data: allLocations } = await useAsyncData(async () => {
    const { data, error } = await api.locations.getAll();
    if (error) {
      console.error("位置数据加载失败:", error);
      toast.error(t("reports.location_label_generator.toast.failed_to_load"));
      return [];
    }
    console.log("位置数据加载成功:", data?.length || 0, "个位置");
    return data || [];
  });

  /**
   * 计算需要生成的位置标签数据
   * 优先使用实际位置数据，如果没有则使用测试数据
   */
  const locations = computed(() => {
    const items: LocationLabelData[] = [];
    
    // 获取所有实际存在的位置
    const existingLocations = allLocations.value || [];
    
    console.log('当前位置数据:', existingLocations);
    
    if (existingLocations.length > 0) {
      // 有实际数据，使用真实位置（UUID格式ID，不按数字范围过滤）
      const sortedLocations = [...existingLocations].sort((a, b) => {
        // 按名称排序或使用原始顺序
        return (a.name || a.id).localeCompare(b.name || b.id);
      });
      
      for (const location of sortedLocations) {
        const qrUrl = getLocationQRCodeUrl(location.id);
        console.log(`生成位置标签: ${location.name}, QR: ${qrUrl}`);
        
        items.push({
          url: qrUrl,
          name: location.name || `位置 ${location.id}`,
          locationID: location.id, // 直接使用UUID作为位置ID
          description: location.description || ""
        });
      }
    } else {
      // 没有实际数据，使用测试数据（数字ID）
      console.log('使用测试数据，范围:', displayProperties.locationRange, '-', displayProperties.locationRangeMax);
      
      for (let i = displayProperties.locationRange; i <= displayProperties.locationRangeMax; i++) {
        const qrUrl = getLocationQRCodeUrl(i.toString());
        console.log(`生成测试标签: 位置 ${i}, QR: ${qrUrl}`);
        
        items.push({
          url: qrUrl,
          name: `位置 ${i}`,
          locationID: fmtLocationID(i.toString()),
          description: "测试位置"
        });
      }
    }
    
    console.log('最终标签数据:', items);
    return items;
  });

  type Row = {
    items: LocationLabelData[];
  };

  type Page = {
    rows: Row[];
  };

  const pages = ref<Page[]>([]);

  /**
   * 计算分页
   * 根据标签尺寸和页面设置计算每页的标签布局
   */
  function calcPages() {
    console.log('开始计算分页...');
    
    const input: LabelOptionInput = {
      measure: displayProperties.measure,
      page: {
        height: displayProperties.pageHeight,
        width: displayProperties.pageWidth,
        pageTopPadding: displayProperties.pageTopPadding,
        pageBottomPadding: displayProperties.pageBottomPadding,
        pageLeftPadding: displayProperties.pageLeftPadding,
        pageRightPadding: displayProperties.pageRightPadding,
      },
      cardHeight: displayProperties.cardHeight,
      cardWidth: displayProperties.cardWidth,
    };

    out.value = calculateGridData(input);
    console.log('网格计算结果:', out.value);

    const calc: Page[] = [];
    const perPage = out.value.rows * out.value.cols;
    const itemsCopy = [...locations.value];
    
    console.log(`每页最多 ${perPage} 个标签 (行:${out.value.rows}, 列:${out.value.cols})`);
    console.log(`总共 ${itemsCopy.length} 个位置数据`);

    // 按页分组标签数据
    while (itemsCopy.length > 0) {
      const page: Page = { rows: [] };

      for (let i = 0; i < perPage; i++) {
        const item = itemsCopy.shift();
        if (!item) break;

        if (i % out.value.cols === 0) {
          page.rows.push({ items: [] });
        }

        page.rows[page.rows.length - 1].items.push(item);
      }

      calc.push(page);
      console.log(`添加页面 ${calc.length}, 行数: ${page.rows.length}`);
    }

    pages.value = calc;
    console.log(`分页完成，总共 ${pages.value.length} 页`);
  }

  /**
   * 增强版打印功能 - 解决预览正常但打印空白的问题
   * 确保实际打印输出与预览一致
   */
  async function print() {
    console.log('开始增强版打印...');
    
    // 检查数据可用性
    if (!pages.value || pages.value.length === 0 || !locations.value || locations.value.length === 0) {
      console.error('没有可打印的数据');
      toast.error('没有可打印的数据，请检查设置');
      return;
    }

    console.log(`准备打印 ${pages.value.length} 页，包含 ${locations.value.length} 个位置标签`);
    
    try {
      // 步骤1: 确保Vue组件和DOM完全渲染
      await nextTick();
      console.log('Vue组件渲染完成');
      
      // 步骤2: 图片预加载检查机制
      const allImages = document.querySelectorAll('section img');
      console.log(`检查 ${allImages.length} 个二维码图片...`);
      
      const imagePromises = Array.from(allImages).map((imgElement, index) => {
        return new Promise((resolve, reject) => {
          const img = imgElement as HTMLImageElement;
          if (img.complete && img.naturalHeight !== 0) {
            console.log(`图片 ${index + 1} 已加载`);
            resolve(img);
          } else {
            const timeout = setTimeout(() => {
              console.warn(`图片 ${index + 1} 加载超时`);
              reject(new Error(`图片加载超时: ${img.src}`));
            }, 10000); // 10秒超时
            
            img.onload = () => {
              clearTimeout(timeout);
              console.log(`图片 ${index + 1} 加载成功`);
              resolve(img);
            };
            
            img.onerror = () => {
              clearTimeout(timeout);
              console.error(`图片 ${index + 1} 加载失败: ${img.src}`);
              reject(new Error(`图片加载失败: ${img.src}`));
            };
            
            // 添加缓存破坏参数防止图片缓存问题
            if (img.src && !img.src.includes('?t=')) {
              img.src = img.src + '?t=' + Date.now();
            }
          }
        });
      });
      
      // 等待所有图片加载完成
      try {
        await Promise.all(imagePromises);
        console.log('所有二维码图片加载完成');
      } catch (error) {
        const errorMessage = error instanceof Error ? error.message : String(error);
        console.warn('部分图片加载失败，但继续打印:', errorMessage);
        toast.warning('部分二维码可能未完全加载，请检查打印结果');
      }
      
      // 步骤3: 执行打印
      toast.info('正在准备打印，请稍候...');
      
      // 等待一小段时间确保样式应用
      setTimeout(() => {
        console.log('开始打印...');
        window.print();
      }, 1000);
      
    } catch (error) {
      console.error('打印准备过程出错:', error);
      toast.error('打印准备失败，请重试');
    }
  }

  watch(allLocations, (newLocations) => {
    if (!newLocations || newLocations.length === 0) {
      // 如果没有位置数据，使用默认值1-8（仅测试数据使用）
      displayProperties.locationRange = 1;
      displayProperties.locationRangeMax = 8;
    }
    calcPages();
  }, { immediate: true });

  watch(displayProperties, () => {
    calcPages();
  });

  // 确保组件挂载后立即计算页面
  onMounted(() => {
    calcPages();
  });
</script>

<template>
  <div>
    <!-- 页面容器：使用标准布局 -->
    <div class="container mx-auto px-4 py-8">
      <!-- 页面标题和说明 -->
      <div class="bg-white rounded-lg shadow-md p-6 mb-8">
        <div class="flex items-center mb-4">
          <MdiMapMarker class="mr-3 h-8 w-8 text-primary" />
          <h1 class="text-3xl font-bold">{{ t("reports.location_label_generator.title") }}</h1>
        </div>
        
        <!-- 功能说明 -->
        <div class="text-gray-600 space-y-2">
          <p>{{ t("tools.reports_set.location_labels_sub", "为您的位置生成带有二维码的可打印PDF标签。这些标签可以提前打印并应用到物理位置，帮助追踪物品存放位置。") }}</p>
          <p class="text-sm">{{ t("reports.label_generator.qr_code_example") }} {{ displayProperties.baseURL }}/location/{location_id}</p>
        </div>
        
        <!-- 位置数据提示 -->
        <div v-if="allLocations && allLocations.length === 0" class="bg-blue-50 border-l-4 border-blue-400 text-blue-700 p-4 mt-4 rounded-md">
          <p class="font-medium">{{ t("reports.location_label_generator.no_locations_title", "暂无位置数据") }}</p>
          <p class="text-sm mt-1">{{ t("reports.location_label_generator.no_locations_message", "当前没有保存的位置数据，系统正在显示测试数据。您可以添加实际位置后再来生成标签。") }}</p>
          <div class="mt-2">
            <NuxtLink to="/locations" class="text-sm text-blue-600 hover:text-blue-800 underline">
              {{ t("menu.locations", "前往位置管理") }}
            </NuxtLink>
          </div>
        </div>
      </div>
      
      <!-- 分隔线 -->
      <div class="my-6">
        <Separator />
      </div>

      <!-- 设置面板 -->
      <div class="bg-white rounded-lg shadow-md p-6 mb-8">
        <h2 class="text-xl font-bold mb-4">{{ t('reports.label_generator.settings') }}</h2>
        
        <!-- 设置输入区域：网格布局显示所有设置项 -->
        <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mb-6">
          <div v-for="prop in propertyInputs" :key="prop.ref" class="flex flex-col"
               v-show="prop.ref !== 'locationRange' && prop.ref !== 'locationRangeMax' || (!allLocations || allLocations.length === 0)">
            <Label :for="`input-${prop.ref}`" class="mb-1 font-medium text-sm">
              {{ prop.label }}
            </Label>
            <Input
              :id="`input-${prop.ref}`"
              v-model="displayProperties[prop.ref] as string | number"
              :type="prop.type ? prop.type : 'number'"
              step="0.01"
              :placeholder="t('reports.label_generator.input_placeholder')"
              class="w-full"
            />
          </div>
        </div>

        <!-- 边框显示开关和其他选项 -->
        <div class="mb-6">
          <div class="flex items-center gap-6 py-4">
            <div class="flex items-center gap-2">
              <Checkbox id="borderedLabels" v-model:checked="bordered" />
              <Label class="cursor-pointer" for="borderedLabels">
                {{ t("reports.label_generator.bordered_labels") }}
              </Label>
            </div>
            
            <div class="flex items-center gap-2">
              <Button 
                @click="displayProperties.includeURLInQR = !displayProperties.includeURLInQR"
                :variant="displayProperties.includeURLInQR ? 'default' : 'outline'"
                size="sm">
                {{ displayProperties.includeURLInQR ? t('reports.label_generator.include_url_in_qr', '包含网址') : t('reports.label_generator.exclude_url_in_qr', '不含网址') }}
              </Button>
              <span class="text-xs text-gray-500 font-mono">
                {{ displayProperties.includeURLInQR ? `${displayProperties.baseURL}/location/${fmtLocationID(displayProperties.locationRange)}` : `/location/${fmtLocationID(displayProperties.locationRange)}` }}
              </span>
            </div>
          </div>
        </div>

        <!-- 操作按钮区域 -->
        <div class="mt-6">
          <Button size="lg" class="w-full bg-primary hover:bg-primary/90 transition-colors mb-4"
            @click="calcPages">
            {{ t("reports.label_generator.generate_page") }}
          </Button>
          
          <Button @click="print" class="w-full" variant="outline">
            <MdiPrinter class="mr-2 h-4 w-4" />
            {{ t("reports.label_generator.print") }}
          </Button>
        </div>
      </div>
    </div>

    <!-- 标签打印预览区域 -->
    <div class="container mx-auto mt-8 mb-16 preview-container">
      <div class="flex flex-col items-center">
        <!-- 预览标题 -->
        <div class="flex items-center justify-between w-full max-w-4xl mb-6 print:hidden">
          <h3 class="text-lg font-semibold">{{ t("reports.location_label_generator.preview") }}</h3>
          <div class="text-sm text-gray-600">
            {{ t("reports.location_label_generator.page_info", { currentPage: 1, totalPages: pages.length }) }}
            <span v-if="allLocations && allLocations.length === 0" class="ml-2 text-orange-600 font-medium">
              ({{ t("reports.label_generator.test_data", "测试数据") }})
            </span>
          </div>
        </div>

        <!-- 空状态 -->
        <div v-if="locations.length === 0" class="text-center py-8 print:hidden">
          <MdiMapMarkerOff class="mx-auto h-12 w-12 text-gray-400" />
          <h3 class="mt-2 text-sm font-medium text-gray-900">{{ t("reports.label_generator.no_labels", "没有可显示的标签") }}</h3>
          <p class="mt-1 text-sm text-gray-500">{{ t("reports.label_generator.adjust_settings", "请检查位置数据或调整设置") }}</p>
        </div>

        <!-- 单个页面：根据计算结果动态生成 -->
        <section
          v-for="(page, pi) in pages"
          :key="pi"
          class="mb-8 border-2 print:border-none shadow-md"
          :style="{
            paddingTop: `${out.page.pt}${out.measure}`,
            paddingBottom: `${out.page.pb}${out.measure}`,
            paddingLeft: `${out.page.pl}${out.measure}`,
            paddingRight: `${out.page.pr}${out.measure}`,
            width: `${out.page.width}${out.measure}`,
            background: `white`,
            color: `black`,
          }"
        >
          <!-- 标签行：按行排列标签 -->
          <div
            v-for="(row, ri) in page.rows"
            :key="ri"
            class="flex flex-wrap break-inside-avoid mb-4"
            :style="{
              columnGap: `${out.gapX}${out.measure}`,
              rowGap: `${out.gapY}${out.measure}`,
            }"
          >
            <!-- 单个位置标签：显示二维码和位置名称（统一布局） -->
            <div
              v-for="(location, idx) in row.items"
              :key="idx"
              class="flex flex-col justify-center items-center border-2 rounded p-2"
              :class="{
                'border-black': bordered,
                'border-transparent': !bordered,
              }"
              :style="{
                height: `${out.card.height}${out.measure}`,
                width: `${out.card.width}${out.measure}`,
              }"
            >
              <!-- 二维码图片 -->
              <img
                :src="location.url"
                :alt="`位置${location.locationID}二维码`"
                :style="{
                  width: `${Math.min(out.card.width * 0.6, out.card.height * 0.6)}${out.measure}`,
                  height: `${Math.min(out.card.width * 0.6, out.card.height * 0.6)}${out.measure}`,
                }"
                class="rounded mb-1"
              />
              
              <!-- 位置名称 -->
              <div class="text-center text-xs font-semibold text-black leading-tight" 
                   :style="{ fontSize: '0.7rem', maxWidth: '95%' }">
                {{ location.name }}
              </div>
            </div>
          </div>
        </section>
      </div>
    </div>
  </div>
</template>

<style scoped>
/* 打印样式优化：精确控制打印区域 */
@media print {
  /* 隐藏页面主要内容，但不影响预览容器 */
  .container:not(.preview-container),
  .container:not(.preview-container) * {
    visibility: hidden !important;
    display: none !important;
  }
  
  /* 隐藏预览容器中的非标签元素 */
  .preview-container .print\:hidden,
  .preview-container > .flex > *:not(section) {
    visibility: hidden !important;
    display: none !important;
  }
  
  /* Tailwind print:hidden 类支持 */
  .print\:hidden {
    display: none !important;
    visibility: hidden !important;
  }
  
  /* Tailwind print:border-none 类支持 */
  .print\:border-none {
    border: none !important;
  }
  
  /* 确保边框样式在打印时正常工作 */
  .border-2 {
    border-width: 2px !important;
    border-style: solid !important;
  }
  
  .border-black {
    border-color: black !important;
  }
  
  .border-transparent {
    border-color: transparent !important;
  }
  
  /* 确保预览容器可见 */
  .preview-container {
    visibility: visible !important;
    display: block !important;
    position: absolute !important;
    left: 0 !important;
    top: 0 !important;
    width: 100% !important;
    height: 100% !important;
    margin: 0 !important;
    padding: 0.2in !important;
    box-sizing: border-box !important;
    background: white !important;
  }
  
  /* 确保预览容器的直接子元素可见 */
  .preview-container > .flex {
    visibility: visible !important;
    display: flex !important;
  }
  
  /* 只显示标签打印区域及其内容 */
  section,
  section * {
    visibility: visible !important;
    display: block !important;
  }
  
  /* 设置打印页面样式 */
  html, body {
    margin: 0 !important;
    padding: 0 !important;
    background: white !important;
    color: black !important;
    font-family: Arial, sans-serif !important;
  }
  
  /* 标签区域在打印中的布局 */
  section {
    position: relative !important;
    margin: 0 !important;
    padding: 0.2in !important;
    box-sizing: border-box !important;
    box-shadow: none !important;
  }
  
  /* 确保flex布局正常工作 */
  .flex {
    display: flex !important;
  }
  
  .flex-col {
    flex-direction: column !important;
  }
  
  .flex-wrap {
    flex-wrap: wrap !important;
  }
  
  .items-center {
    align-items: center !important;
  }
  
  .justify-center {
    justify-content: center !important;
  }
  
  /* 确保图片正常显示 */
  img {
    display: block !important;
    visibility: visible !important;
    opacity: 1 !important;
    -webkit-print-color-adjust: exact !important;
    print-color-adjust: exact !important;
  }
}

/* 打印区域样式：确保打印效果 */
section {
  margin-bottom: 2rem;    /* 页面间距 */
  page-break-after: always; /* 打印时强制分页 */
}

/* 最后一个页面不需要分页 */
section:last-child {
  page-break-after: avoid;
}

/* 标签边框样式：根据设置显示或隐藏 */
.border-2 {
  border-width: 2px;
  border-style: solid;
}

.border-black {
  border-color: black;
}

.border-transparent {
  border-color: transparent;
}

/* 响应式布局：确保在不同设备上的显示效果 */
@media (max-width: 768px) {
  .grid-cols-2 {
    grid-template-columns: 1fr; /* 移动端单列显示 */
  }
  
  .container {
    padding-left: 1rem;
    padding-right: 1rem;
  }
}
</style>